﻿using CommandService;
using Entity;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Entity.DbEntity;

namespace SysFrameWork
{
    /// <summary>
    /// 钉钉方法类
    /// </summary>
    public class DingHelper
    {
        Tools.ConfigReader config;
        HttpAgreement http;
        Commands cmd;
        ReturnResult rsl;
        Tools.TxtLogHelper txt;
        SystemBLL sysBLL;
        public DingHelper()
        {
            config = new Tools.ConfigReader();
            http = new HttpAgreement();
            cmd = new Commands();
            txt = new Tools.TxtLogHelper();
            sysBLL = new SystemBLL();
        }
        /// <summary>
        /// 钉钉消息发送方法
        /// </summary>
        /// <param name="businessType">数据类型</param>
        /// <param name="bussnessId">关联数据ID</param>
        /// <param name="users">消息接收人员账号</param>
        /// <param name="contents">消息内容</param>
        /// <param name="createuser">创建人</param>
        /// <returns></returns>
        public ReturnResult sendDingMsg(string businessType, string bussnessId, string users, string contents, string createuser)
        {
            rsl = new ReturnResult();
            string msg = "";
            try
            {
                string msgType = "DingDing";
                string userIds = this.getUserDingIdByCode(users, ref msg);
                if (!string.IsNullOrWhiteSpace(msg))
                {
                    sysBLL.AddRecords(businessType, bussnessId, msgType,users, contents,"0",msg,createuser);
                    rsl.Result = false;
                    rsl.Message = msg;
                    return rsl;
                }
                string dingToken = createToken();
                string MessageUrl = "https://oapi.dingtalk.com/message/send?access_token=" + dingToken;
                var json_req = new
                {
                    touser = userIds.TrimEnd('|'), //接受推送userid，不同用户用|分割
                    toparty = "",  //接受推送部门id
                    agentid = config["Ding-AgentId"],
                    msgtype = "text", //推送类型
                    text = new
                    {
                        content = contents + "\n" + DateTime.Now.ToString()
                    }
                };

                string jsonRequest = JsonConvert.SerializeObject(json_req);//将对象转换为json
                                                                           //POST请求 消息推送
                var sr = http.PostJson(MessageUrl, jsonRequest);
                if (!string.IsNullOrWhiteSpace(sr))
                {
                    var obj = JsonConvert.DeserializeObject<JObject>(sr);
                    if (obj["errcode"].ToString() == "0")
                    {
                        rsl.Result = true;
                    }
                    else
                    {
                        rsl.Message = sr;
                    }
                }
                string r = "0";
                if (rsl.Result)
                {
                    r = "1";
                    msg = "成功";
                    rsl.Result = false;
                    rsl.Message = msg;
                }
                else
                {
                    msg = rsl.Message;
                }
                sysBLL.AddRecords(businessType, bussnessId, msgType, users,contents, r, msg, createuser);
            }
            catch (Exception ex)
            {
                txt.AddLogMsg("sendDingMsg方法异常：" + ex.Message);
                rsl.Message = ex.Message;
            }
            return rsl;
        }

        /// <summary>
        /// 根据登录账号获取钉钉id
        /// </summary>
        /// <param name="users">用户账号(多用户用英文逗号隔开)</param>
        /// <param name="msg"></param>
        private string getUserDingIdByCode(string users, ref string msg)
        {
            StringBuilder sb = new StringBuilder();
            if (string.IsNullOrWhiteSpace(users))
            {
                msg = "没有接收用户信息";
                return "";
            }
            var uArr = users.Split(',');
            string usCodes = "";
            foreach (string u in uArr)
            {
                if (!string.IsNullOrWhiteSpace(u))
                {
                    usCodes = usCodes + "'" + u + "',";
                }
            }
            sb.Append("select isnull(userPhone,'') userPhone,isnull(DingID,'') DingID,userCode,userName ");
            sb.Append("from sys_users_info ");
            sb.Append("where userCode in(" + usCodes.TrimEnd(',') + ") and isDel=0 and status='Y'");
            var uTable = cmd.GetDataTable(sb.ToString());
            if (uTable.Rows.Count < 1)
            {
                msg = "所有用户信息错误"; return "";
            }
            string dingIds = "";
            foreach (DataRow r in uTable.Rows)
            {
                if (!string.IsNullOrWhiteSpace(r["DingID"].ToString()))
                {
                    #region 存在钉钉id
                    dingIds = dingIds + r["DingID"].ToString() + "|";
                    #endregion

                }
                else
                {
                    #region 不存在钉钉id 根据电话获取
                    if (string.IsNullOrWhiteSpace(r["userPhone"].ToString()))
                    {
                        msg = string.Format("用户电话不允许为空：{0}({1})", r["userName"].ToString(), r["userCode"].ToString());
                        return "";
                    }
                    string ding = this.getUserIdByPhone(r["userPhone"].ToString());
                    if (string.IsNullOrWhiteSpace(ding))
                    {
                        msg = string.Format("钉钉Id获取失败：{0}({1})", r["userName"].ToString(), r["userCode"].ToString());
                        return "";
                    }
                    dingIds = dingIds + ding + "|";
                    #endregion
                }
            }
            return dingIds;
        }
        /// <summary>
        /// 根据电话号码获取用户的钉钉ID
        /// </summary>
        /// <param name="phone">电话号码</param>
        /// <returns></returns>
        private string getUserIdByPhone(string phone)
        {
            try
            {
                StringBuilder sb = new StringBuilder();
                string dingToken = this.createToken();
                string url = "https://oapi.dingtalk.com/topapi/v2/user/getbymobile?access_token=" + dingToken;
                var json_req = new
                {
                    mobile = phone
                };
                string jsonRequest = JsonConvert.SerializeObject(json_req);//将对象转换为json
                var msg = http.PostJson(url, jsonRequest);
                if (!string.IsNullOrWhiteSpace(msg))
                {
                    var obj = JsonConvert.DeserializeObject<JObject>(msg);
                    if (obj["errcode"].ToString() == "0")
                    {
                        sb.Append("update sys_users_info set DingID='" + obj["result"]["userid"].ToString() + "'");
                        sb.Append(" where userPhone='" + phone + "'");
                        cmd.UpdateSql(sb.ToString());
                        return obj["result"]["userid"].ToString();
                    }
                }
                else
                {
                    txt.AddLogMsg("钉钉接口错误:" + msg);
                }
            }
            catch (Exception ex)
            {
                string info = string.Format("参数：{0},错误消息：{1}", phone, ex.Message);
                txt.AddLogMsg("getUserIdByPhone方法异常：" + info);
            }
            return "";
        }
        /// <summary>
        /// 创建钉钉token
        /// </summary>
        /// <returns></returns>
        private string createToken()
        {
            try
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("select * from sys_OtherTokens_records ");
                sb.Append(" where tokenType='Ding' order by id desc");
                var table = cmd.GetDataTable(sb.ToString());
                if (table.Rows.Count > 0)
                {
                    var count = table.Rows[0]["useCount"].ToString();//token使用此时(默认 token至多只允许使用2000次)
                    var time = table.Rows[0]["createtime"].ToString();//token生成时间(有效时间2小时)
                    if (DateTime.Parse(time).AddMinutes(115) < DateTime.Now)
                    {
                        return getDingToken();
                    }
                    else
                    {
                        return table.Rows[0]["token"].ToString();
                    }
                }
                else
                {
                    return getDingToken();
                }

            }
            catch (Exception ex)
            {

            }
            return "";
        }
        /// <summary>
        /// 获取钉钉Token
        /// </summary>
        /// <returns></returns>
        private string getDingToken()
        {
            string url = string.Format("https://oapi.dingtalk.com/gettoken?appkey={0}&appsecret={1}", config["Ding-AppKey"], config["Ding-AppSecret"]);
            var msg = http.Get(url, "");
            if (!string.IsNullOrWhiteSpace(msg))
            {
                var json = JsonConvert.DeserializeObject<JObject>(msg);
                if (json["errcode"].ToString() == "0")
                {
                    string token = json["access_token"].ToString();
                    string sql = string.Format("insert into sys_OtherTokens_records (tokenType,token,createtime) values('{0}','{1}','{2}')", "Ding", token, DateTime.Now.ToString());
                    cmd.UpdateSql(sql);
                    return token;
                }
            }
            return "";
        }
    }
}
